# Frontend Deployment Script - Windows PowerShell Version
param(
    [string]$Environment = "sit",
    [string]$ServerHost = "168.61.12.83",
    [string]$ServerUser = "appadmin", 
    [string]$ServerPassword = "",
    [string]$RemoteDir = "/home/appadmin/app/codeknowledge-web/web",
    [string]$NginxPort = "13000",
    [string]$SSHKeyPath = ""  # Optional SSH private key path
)

# Display configuration information
Write-Host "=============== Frontend Deployment Config ===============" -ForegroundColor Cyan
Write-Host "Environment: $Environment" -ForegroundColor Yellow

# 根据环境选择服务器配置
switch ($Environment) {
    { $_ -in @("dev", "sit", "prod") } {
        if (-not $ServerHost) { $ServerHost = "168.61.12.83" }
        if (-not $ServerPassword) { $ServerPassword = "Qinxiao#12345" }
        Write-Host "Server: 服务器一 ($ServerHost)" -ForegroundColor Yellow
    }
    { $_ -in @("odev", "oprod") } {
        if (-not $ServerHost) { $ServerHost = "115.159.214.105" }
        if (-not $ServerPassword) { $ServerPassword = "Sunny1234" }
        Write-Host "Server: 服务器二 ($ServerHost)" -ForegroundColor Yellow
    }
    default {
        Write-Host "不支持的环境: $Environment，支持的环境: dev, sit, prod, odev, oprod" -ForegroundColor Red
        exit 1
    }
}

Write-Host "Server: $ServerUser@$ServerHost" -ForegroundColor Yellow
Write-Host "Deploy Directory: $RemoteDir" -ForegroundColor Yellow
Write-Host "Nginx Port: $NginxPort" -ForegroundColor Yellow

if ($SSHKeyPath -and (Test-Path $SSHKeyPath)) {
    Write-Host "SSH Key: $SSHKeyPath" -ForegroundColor Green
    Write-Host "Authentication: SSH Key (passwordless)" -ForegroundColor Green
} else {
    Write-Host "SSH Key: Not provided or not found" -ForegroundColor Yellow
    Write-Host "Authentication: Password" -ForegroundColor Yellow
}
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host ""

function Check-Requirements {
    Write-Host "[1/5] Checking deployment environment..." -ForegroundColor Yellow
    
    # Check Node.js
    try {
        $nodeVersion = node --version 2>&1
        Write-Host "✓ Node.js: $nodeVersion" -ForegroundColor Green
    } catch {
        Write-Host "✗ Node.js not installed or not in PATH" -ForegroundColor Red
        exit 1
    }
    
    # Check npm
    try {
        $npmVersion = npm --version 2>&1
        Write-Host "✓ npm: $npmVersion" -ForegroundColor Green
    } catch {
        Write-Host "✗ npm not installed or not in PATH" -ForegroundColor Red
        exit 1
    }
    
    # Check SSH authentication method
    if ($SSHKeyPath -and (Test-Path $SSHKeyPath)) {
        Write-Host "✓ SSH Key found: $SSHKeyPath" -ForegroundColor Green
        Write-Host "  Using key-based authentication (no password required)" -ForegroundColor Cyan
    } else {
        Write-Host "! SSH Key not provided or not found" -ForegroundColor Yellow
        Write-Host "  Will use password authentication" -ForegroundColor Cyan
        Write-Host "  Tip: Use SSH keys for passwordless authentication" -ForegroundColor Gray
    }
    
    # Check SCP
    try {
        if (Get-Command pscp -ErrorAction SilentlyContinue) {
            Write-Host "✓ PSCP (PuTTY) available" -ForegroundColor Green
        } elseif (Get-Command scp -ErrorAction SilentlyContinue) {
            Write-Host "✓ SCP available" -ForegroundColor Green
        } else {
            Write-Host "✗ SCP not available, please install Git for Windows, OpenSSH, or PuTTY" -ForegroundColor Red
            exit 1
        }
    } catch {
        Write-Host "✗ SCP not available, please install Git for Windows, OpenSSH, or PuTTY" -ForegroundColor Red
        exit 1
    }
}

function Build-Frontend {
    Write-Host "[2/5] Building frontend project..." -ForegroundColor Yellow
    
    Write-Host "Installing dependencies..." -ForegroundColor Cyan
    & npm install
    if ($LASTEXITCODE -ne 0) {
        Write-Host "npm install failed" -ForegroundColor Red
        exit 1
    }
    
    Write-Host "Building production bundle..." -ForegroundColor Cyan
    & npm run build
    if ($LASTEXITCODE -ne 0) {
        Write-Host "Frontend build failed" -ForegroundColor Red
        exit 1
    }
    
    Write-Host "✓ Frontend build completed" -ForegroundColor Green
}

function Create-DeployPackage {
    Write-Host "[3/5] Creating deployment package..." -ForegroundColor Yellow
    
    # Check build directory
    if (!(Test-Path "build")) {
        Write-Host "Build directory does not exist, please build project first" -ForegroundColor Red
        exit 1
    }
    
    # Create ZIP file
    $timestamp = Get-Date -Format "yyyyMMddHHmmss"
    $zipFile = "code-knowledge-web-$timestamp.zip"
    $zipPath = "build\$zipFile"
    
    Write-Host "Creating ZIP package: $zipFile" -ForegroundColor Cyan
    
    # Use PowerShell's Compress-Archive
    try {
        Compress-Archive -Path "build\*" -DestinationPath $zipPath -Force
        Write-Host "✓ Deployment package created: $zipFile" -ForegroundColor Green
    } catch {
        Write-Host "✗ Failed to create deployment package: $_" -ForegroundColor Red
        exit 1
    }
    
    return $zipFile
}

function Upload-Frontend {
    param([string]$ZipFile)
    
    Write-Host "[4/5] Uploading deployment package to server..." -ForegroundColor Yellow
    
    $localZip = "build\$ZipFile"
    $remoteTarget = "${ServerUser}@${ServerHost}:${RemoteDir}/"
    
    try {
        Write-Host "Uploading $ZipFile ..." -ForegroundColor Cyan
        
        # Check if SSH key is provided and exists
        if ($SSHKeyPath -and (Test-Path $SSHKeyPath)) {
            Write-Host "Using SSH key authentication: $SSHKeyPath" -ForegroundColor Green
            scp -i $SSHKeyPath $localZip $remoteTarget
        } elseif (Get-Command pscp -ErrorAction SilentlyContinue) {
            Write-Host "Using PSCP with password authentication..." -ForegroundColor Yellow
            pscp -pw $ServerPassword $localZip $remoteTarget
        } else {
            Write-Host "Using SCP with password authentication..." -ForegroundColor Yellow
            Write-Host "Please enter password: $ServerPassword" -ForegroundColor Cyan
            scp $localZip $remoteTarget
        }
        
        if ($LASTEXITCODE -ne 0) {
            throw "SCP upload failed"
        }
        
        Write-Host "✓ Upload completed" -ForegroundColor Green
    } catch {
        Write-Host "Upload failed: $_" -ForegroundColor Red
        exit 1
    }
}

function Deploy-Frontend {
    param([string]$ZipFile)
    
    Write-Host "[5/5] Remote frontend deployment..." -ForegroundColor Yellow
    
    try {
        Write-Host "Executing remote deployment with step-by-step process..." -ForegroundColor Cyan
        
        # Create deployment commands that match bash script logic
        $deployCommands = @(
            "cd $RemoteDir",
            "echo 'Step 1: Backing up current deployment...'",
            "if [ -d `"static`" ]; then mv static static_backup_`$(date +%Y%m%d%H%M%S) || true; fi",
            "echo 'Step 2: Extracting new deployment package...'",
            "unzip -o `"$ZipFile`"",
            "echo 'Step 3: Cleaning up deployment package...'",
            "rm -f `"$ZipFile`"",
            "echo 'Step 4: Deployment verification...'",
            "if [ -f `"index.html`" ]; then echo 'Frontend deployment completed successfully!'; else echo 'Frontend deployment may have failed - index.html not found'; exit 1; fi"
        )
        
        $sshCommands = $deployCommands -join "; "
        
        if ($SSHKeyPath -and (Test-Path $SSHKeyPath)) {
            Write-Host "Using SSH key authentication for deployment..." -ForegroundColor Green
            ssh -i $SSHKeyPath "${ServerUser}@${ServerHost}" $sshCommands
        } elseif (Get-Command plink -ErrorAction SilentlyContinue) {
            Write-Host "Using PuTTY plink with password authentication..." -ForegroundColor Yellow
            plink -pw $ServerPassword "${ServerUser}@${ServerHost}" $sshCommands
        } else {
            Write-Host "Please enter password for SSH execution: $ServerPassword" -ForegroundColor Cyan
            ssh "${ServerUser}@${ServerHost}" $sshCommands
        }
        
        if ($LASTEXITCODE -ne 0) {
            throw "Remote deployment failed"
        }
        
        Write-Host "✓ Remote deployment completed successfully" -ForegroundColor Green
    } catch {
        Write-Host "Deployment failed: $_" -ForegroundColor Red
        exit 1
    }
}

function Show-Complete {
    Write-Host "" 
    Write-Host "Frontend deployment completed!" -ForegroundColor Green
    Write-Host "Application URL: http://${ServerHost}:${NginxPort}" -ForegroundColor Cyan
    Write-Host "Deploy Directory: $RemoteDir" -ForegroundColor Cyan
    Write-Host "Environment: $Environment" -ForegroundColor Cyan
}

# Main execution flow
try {
    Write-Host "Starting Windows frontend deployment process..." -ForegroundColor Magenta
    Write-Host ""
    
    Check-Requirements
    Build-Frontend
    $zipFile = Create-DeployPackage
    Upload-Frontend $zipFile
    Deploy-Frontend $zipFile
    Show-Complete
    
} catch {
    Write-Host "Deployment failed: $_" -ForegroundColor Red
    exit 1
}